package com.ce.util;

import java.beans.PropertyDescriptor;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.sun.java.util.jar.pack.*;

import javassist.bytecode.stackmap.TypeData;
import org.apache.commons.beanutils.PropertyUtils;

import com.ce.framework.context.FrameworkContext;
import com.ce.framework.datamaintain.logic.IBaseLogic;
import com.ce.framework.datamaintain.logic.ISQLMapper;
import com.ce.framework.exception.AppException;
import com.ce.framework.util.LogUtil;

public class DbUtil {

	private static IBaseLogic baseLogic;
	
	public static ISQLMapper<String> stringMapper = new ISQLMapper<String>(){
		public String fromSQLQuery(ResultSet rs, int num) {
			try {
				return rs.getString(1);
			} catch (SQLException e) {
				e.printStackTrace();
				return null;
			}
		}
	};
	
	private static Object[] emptyParam=new Object[0];
	
	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:31:28
	* 功能描述: 执行SQL语句查询数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @return			以整型数字格式返回数据集中的第一行第一列中的数据
	*/
	public static int getFirstIntSqlQuery(String sql){
		return getFirstIntSqlQuery(sql,emptyParam);
	}

	public static int getFirstIntSqlQuery(String sql,Map<String,Object> params){
		return getFirstIntSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}
	public static int getFirstIntSqlQuery(String sql,Object[] params){
		String res = getFirstStringSqlQuery(sql,params);
		int val = 0;
		try {
			if(res!=null){
				val = Integer.parseInt(res);
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return val;
	}
	
	
	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:31:28
	* 功能描述: 执行SQL语句查询数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @return			以整型数字格式返回数据集中的第一行第一列中的数据
	*/
	public static double getFirstDoubleSqlQuery(String sql){
		return getFirstDoubleSqlQuery(sql,emptyParam);
	}

	public static double getFirstDoubleSqlQuery(String sql,Map<String,Object> params){
		return getFirstDoubleSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}
	public static double getFirstDoubleSqlQuery(String sql,Object[] params){
		String res = getFirstStringSqlQuery(sql,params);
		double val = 0;
		try {
			if(res!=null){
				val = Double.parseDouble(res);
			}
		}catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return val;
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:30:51
	* 功能描述: 执行SQL语句查询数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @return			以字符串格式返回数据集中的第一行第一列中的数据
	*/
	public static String getFirstStringSqlQuery(String sql){
		return getFirstStringSqlQuery(sql,emptyParam);
	}
	public static String getFirstStringSqlQuery(String sql,Map<String,Object> params){
		return getFirstStringSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}
	private static Object[] getParams(String sql,Map<String,Object> params){
		Pattern pat = Pattern.compile("\\$\\{([^\\}]+)\\}");
		Matcher mat = pat.matcher(sql);
		List<Object> paraml = new ArrayList<Object>();
		int index = 0;
		while(mat.find()){
			String pa = mat.group(1);
			Object value = null;
			try {
				value = params.get(pa);
			} catch (Exception e) {
				e.printStackTrace();
			}
			paraml.add(index++,value);
		}
		Object[] param = new Object[index];
		for(int i=0;i<index;i++){
			param[i] = paraml.get(i);
		}
		return param;
	}
	public static String getFirstStringSqlQuery(String sql,Object[] params){
		List<String> list = executeSqlQuery("select * from ("+sql+") sql_$1 where rownum=1",stringMapper,params);
		if(list.isEmpty()){
			return null;
		}
		return list.get(0);
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2013-11-2  下午05:10:47
	* 功能描述: 查询只有一列字符串的数据集
	* 方法的参数和返回值: 
	* @param sql
	* @return
	*/
	public static List<String> executeStringSqlQuery(String sql){
		return executeSqlQuery(sql,stringMapper);
	}
	/**
	 * 开发人： andy
	 * 开发时间： 2013-6-13 下午01:45:26
	 * 功能描述：查询只有一列字符串的数据集
	 * 方法的参数和返回值
	 * @param sql
	 * @param params
	 * @return
	 * List 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	public static List<String> executeStringSqlQuery(String sql,Object[] params){
		return executeSqlQuery(sql,stringMapper,params);
	}
	public static List<String> executeStringSqlQuery(String sql,Map<String,Object> params){
		return executeStringSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-11-6  下午02:53:11
	* 功能描述: 查询有一列或两列的数据，并将每行数据封闭成为一个HashMap，第一列做为key,第二列做为value
	* 方法的参数和返回值: 
	* @param sql
	* @return
	*/
	public static HashMap<Object, Object> getMapSqlQuery(String sql) {
		return getMapSqlQuery(sql,emptyParam);
	}
	/**
	 * 开发人： andy
	 * 开发时间： 2013-6-13 下午01:44:29
	 * 功能描述：查询有一列或两列的数据，并将每行数据封闭成为一个HashMap，第一列做为key,第二列做为value
	 * 方法的参数和返回值
	 * @param sql
	 * @param params
	 * @return
	 * HashMap 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	public static HashMap<Object, Object> getMapSqlQuery(String sql,Object[] params) {
		final HashMap<Object, Object> map = new LinkedHashMap<Object, Object>();
		executeSqlQuery(sql,new ISQLMapper<Object>(){
			public Object fromSQLQuery(ResultSet rs, int num) {
				try {
					if(rs.getMetaData().getColumnCount()>1){
						map.put(rs.getObject(1), rs.getObject(2));
					}
					else{
						map.put(rs.getObject(1), rs.getObject(1));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return null;
			}
		},params);
		return map;
	}
	public static HashMap<Object, Object> getMapSqlQuery(String sql,Map<String,Object> params){
		return getMapSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:30:37
	* 功能描述: 执行SQL语句查询数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @param mapper		数据库行的映射器，将数据库中的行转换为一个对象
	* @return			查询后得到的数据集，集合中的每个对象表示数据库中的一行
	*/
	public static <T> List<T> executeSqlQuery(String sql,ISQLMapper<? extends T> mapper){
		return executeSqlQuery(sql,mapper,emptyParam);
	}

	/**
	* 开发人：andy
	* 开发日期: 2011-06-13  13:38:32
	* 功能描述: 执行SQL语句查询数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @param mapper		数据库行的映射器，将数据库中的行转换为一个对象
	* @param params		SQL语句的参数列表
	* @return			查询后得到的数据集，集合中的每个对象表示数据库中的一行
	*/
	public static <T> List<T> executeSqlQuery(String sql,ISQLMapper<? extends T> mapper,Object[] params){
		Connection con = getConnection();
		List<T> list = new ArrayList<T>();
		try {
			PreparedStatement st = con.prepareStatement(sql);
			LogUtil.logSql(sql+"  "+getObjAryString(params));
			if(params!=null){
				for(int i=0;i<params.length;i++){
					st.setObject(i+1, transDbType(params[i]));
				}
			}
			st.execute();
			ResultSet rs = st.getResultSet();
			int row = 0;
			while(rs.next()){
				list.add(mapper.fromSQLQuery(rs, row++));
			}
			rs.close();
			st.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		finally{
			if(con!=null)
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}
		return list;
	}

	public static <T> List<T> executeSqlQuery(String sql,ISQLMapper<? extends T> mapper,Map<String,Object> params){
		return executeSqlQuery(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),mapper,getParams(sql,params));
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:29:23
	* 功能描述: 执行SQL语句更新数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号
	* @return			SQL语句执行成功后影响到的行数，如果返回-1表示SQL语句执行失败
	*/
	public static int executeSqlUpdate(String sql){
		return executeSqlUpdate(sql,emptyParam);
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:27:44
	* 功能描述: 执行SQL语句更新数据库内容
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号，参数以?代替
	* @param params		SQL语句中的参数，可以为null
	* @return			SQL语句执行成功后影响到的行数，如果返回-1表示SQL语句执行失败
	*/
	public static int executeSqlUpdate(String sql,Object[] params){
		List<Object[]> paramsList = null;
		if(params!=null&&params.length>0){
			paramsList = new ArrayList<Object[]>();
			paramsList.add(params);
		}
		return executeSqlUpdateMultiRow(sql,paramsList);
	}

	public static int executeSqlUpdate(String sql,Map<String,Object> params){
		return executeSqlUpdate(sql.replaceAll("'?\\$\\{([^\\}]+)\\}'?", "?"),getParams(sql,params));
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-21  下午01:11:56
	* 功能描述: 对同一条SQL语句添加多行数据，用于insert语句，可一次添加多条数据
	* 方法的参数和返回值: 
	* @param sql		可执行SQL语句，语句末尾不能带有分号，参数以?代替
	* @param paramsList		SQL语句中的参数，可以为null
	* @return			SQL语句执行成功后影响到的行数，如果返回-1表示SQL语句执行失败
	*/
	public static int executeSqlUpdateMultiRow(String sql,Collection<Object[]> paramsList){
		List<String> sqls = new ArrayList<String>();
		sqls.add(sql);
		List<Collection<Object[]>> paramsLists = new ArrayList<Collection<Object[]>>();
		paramsLists.add(paramsList);
		return executeSqlUpdatePrivate(sqls,paramsLists);
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:24:57
	* 功能描述: 执行SQL语句更新数据库内容
	* 方法的参数和返回值: 
	* @param sqlList	可执行SQL语句的集合，语句末尾不能带有分号
	* @return			SQL语句执行成功后影响到的行数，如果返回-1表示SQL语句执行失败
	*/
	public static int executeSqlUpdate(Collection<String> sqlList){
		List<Collection<Object[]>> paramsLists = new ArrayList<Collection<Object[]>>();
		for(int i=0;i<sqlList.size();i++){
			paramsLists.add(new ArrayList<Object[]>());
		}
		return executeSqlUpdatePrivate(sqlList, paramsLists);
	}

	public static int executeSqlUpdate(Collection<String> sqlList,Collection<Object[]> paramsList){
		List<Collection<Object[]>> paramsLists = new ArrayList<Collection<Object[]>>();
		Iterator<Object[]> it = paramsList.iterator();
		while(it.hasNext()){
			List<Object[]> params = new ArrayList<Object[]>();
			params.add(it.next());
			paramsLists.add(params);
		}
		return executeSqlUpdatePrivate(sqlList, paramsLists);
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:24:57
	* 功能描述: 执行SQL语句更新数据库内容
	* 方法的参数和返回值: 
	* @param sqlList	可执行SQL语句的集合，语句末尾不能带有分号
	* @param  			paramsLists，可以为null
	* @return			SQL语句执行成功后影响到的行数，如果返回-1表示SQL语句执行失败
	*/
	private static int executeSqlUpdatePrivate(Collection<String> sqlList,Collection<Collection<Object[]>> paramsLists){
		Connection con = getConnection();
		if(con==null)
			return -1;
		int result = 0;
		boolean oldAutoCommit = true;
		try {
			oldAutoCommit = con.getAutoCommit();
			con.setAutoCommit(false);
			Iterator<String> it = sqlList.iterator();
			Iterator<Collection<Object[]>>it2 = paramsLists.iterator();
			while(it.hasNext()&&it2.hasNext()){
				String sql = it.next();
				Collection<Object[]> paramsList = it2.next();
				if(paramsList==null||paramsList.size()==0){//如果SQL语句对应的参数矩阵为空，直接执行SQL语句
					Statement st = con.createStatement();
					LogUtil.logSql(sql);
					result += st.executeUpdate(sql);
					st.close();
				}
				else{//否则对参数列表进行遍历，顺序执行参数矩阵中的行
					Iterator<Object[]> it3 = paramsList.iterator();
					while(it3.hasNext()){
						Object[] params = it3.next();
						PreparedStatement pst = con.prepareStatement(sql);
						for(int i=0;i<params.length;i++){
							pst.setObject((i+1), transDbType(params[i]));
						}
						LogUtil.logSql(sql+"  "+getObjAryString(params));
						result += pst.executeUpdate();
						pst.close();
					}
				}
			}
			con.commit();
			con.setAutoCommit(oldAutoCommit);
		} catch (SQLException e) {
			result = -1;
			e.printStackTrace();
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
		finally{
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	public static Map<String,Object> obj2map(Object obj){
		Map<String,Object> map = new HashMap<String,Object>();
		if(obj!=null){
			for(PropertyDescriptor p:PropertyUtils.getPropertyDescriptors(obj)){
				try {
					map.put(p.getName(), PropertyUtils.getProperty(obj, p.getName()));
				} catch (Exception e) {
					LogUtil.logError(e);
				}
			}
		}
		return map;
	}
	
	private static String getObjAryString(Object[] param){
		StringBuffer buff = new StringBuffer();
		if(param!=null&&param.length>0){
			for(Object obj:param){
				buff.append(",").append(obj==null?"null":obj.toString());
			}
			return "["+buff.substring(1)+"]";
		}
		return "";
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2013-10-21  下午03:21:00
	* 功能描述: 对参数类型进行转换，目前只转换日期型java.util.Date为java.sql.Timestamp
	* 方法的参数和返回值: 
	* @param o
	* @return
	*/
	private static Object transDbType(Object o){
		if(o instanceof java.util.Date){
			java.util.Date d = (java.util.Date)o;
			return new java.sql.Timestamp(d.getTime());
		}
		return o;
	}

	public static Connection _CONNECTION;
	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:24:40
	* 功能描述: 获取系统数据库连接池中的连接
	* 方法的参数和返回值: 
	* @return
	*/
	public static Connection getConnection() {
		if(_CONNECTION!=null){//方便不起工程直接使用本工具类执行SQL语句
			return _CONNECTION;
		}
		try{
			Object obj=FrameworkContext.getBean("dataSource");
			if(obj==null){
				throw new AppException("在系统中没有找到dataSource的注册对象。");
			}
			DataSource myDataSource=(DataSource)obj;
			Connection conn=myDataSource.getConnection();
			return conn;
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return null;
	}


	public static IBaseLogic getIBaseLogic(){
		if(baseLogic==null){
			try {
				baseLogic = (IBaseLogic)FrameworkContext.getBean("baseLogic");
			} catch (AppException e) {
				e.printStackTrace();
			}
		}
		return baseLogic;
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午04:57:38
	* 功能描述: 通过PO类型名和主键获取PO对象
	* 方法的参数和返回值: 
	* @param name		PO类名
	* @param pk			主键
	* @return
	*/
	public static Object getPOByPk(String name, String pk) {
		try {
			return getIBaseLogic().getPOByPk(name, pk);
		} catch (AppException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2013-11-2  下午04:57:02
	* 功能描述: INSERT数据
	* 方法的参数和返回值: 
	* @param obj
	* @return
	*/
	public static boolean addPo(Object obj){
		try {
			getIBaseLogic().addPo(obj);
		} catch (AppException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-11-2  下午04:57:43
	* 功能描述: UPDATE数据
	* 方法的参数和返回值: 
	* @param obj
	* @return
	*/
	public static boolean updatePo(Object obj){
		try {
			getIBaseLogic().updatePo(obj);
		} catch (AppException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2013-11-2  下午04:57:16
	* 功能描述: 查询HQL语句
	* 方法的参数和返回值: 
	* @param hql
	* @return
	*/
	public static List<?> executeHql(String hql){
		try {
			return getIBaseLogic().searchByHql(hql);
		} catch (AppException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static List<?> executeHql(String hql,Object[] params){
		try {
			return getIBaseLogic().searchByHql(hql,params);
		} catch (AppException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2007-9-19  上午10:21:32
	* 功能描述: 记录用户操作日志
	* 方法的参数和返回值: 
	* @param vcUserName
	* @param vcIpAddr
	* @param vcFunName
	* @param vcUrl
	* @param vcModule
	* @param vcOperate
	* @param vcNote
	*/
	public static void logUserOperate(String vcUserName, String vcIpAddr, String vcFunName, String vcUrl, String vcModule, String vcOperate, String vcNote) {
		Connection conn = null;
		try {
			conn = DbUtil.getConnection();
			CallableStatement st = conn.prepareCall("{call SYS_PK_LOG.LOG_USER_OPERATE(?,?,?,?,?,?,?) }");
			st.setString(1, vcUserName);
			st.setString(2, vcIpAddr);
			st.setString(3, vcFunName);
			st.setString(4, vcUrl);
			st.setString(5, vcModule);
			st.setString(6, vcOperate);
			st.setString(7, vcNote);
			st.execute();
			if (st != null)
				st.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}
	
	/**
	* 开发人：andy
	* 开发日期: 2007-8-20  上午10:57:30
	* 功能描述: 查询SQL，返回Object[]的List对象
	* 方法的参数和返回值: 
	* @param sql
	* @return		List中是Object[]对象或Object对象
	*/
	public static List<?> executeSqlQueryToObj(String sql){

		List<Object> list = new ArrayList<Object>();
		Connection con = null;
		try{
			con = getConnection();
			if(con==null)
				throw new Exception("获取数据库连接失败!");
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(sql);
			int cols = rs.getMetaData().getColumnCount();
			int i=0;
			Object[] row = null;
			while(rs.next()){
				if(cols==1){
					list.add(rs.getObject(1));
				}
				else{
					row = new Object[cols];
					for(i=0;i<cols;i++)
						row[i] = rs.getObject(i+1);
					list.add(row);
				}
			}
			rs.close();
			st.close();
			con.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		finally{
			try {
				if(con!=null && !con.isClosed())
					con.close();
			} catch (SQLException e) {
				
				e.printStackTrace();
			}
		}
		return list;
	}


	/**
	 * 开发人：周路/n
	 * 开发日期: 2017年7月3日18:15:11
	 * 功能描述: 查询SQL，返回Object[]的List对象
	 * 方法的参数和返回值:
	 * 	 * 例子：con=DbUtil.getConnection(Class.forName("oracle.jdbc.driver.OracleDriver"), "jdbc:oracle:thin:@//localhost:1521/orcl", "system", "admin");
	 * @param driver  	=Class.forName("oracle.jdbc.driver.OracleDriver") \n
	 * @param dbUrl		="jdbc:oracle:thin:@//localhost:1521/orcl"   \n
	 * @param userName	="system"	\n
	 * @param userPwd	="admin" \n
	 *
	 * @param sql
	 * @return		List中是Object[]对象或Object对象
	 */
	public static List<?> executeSqlQueryToList_setdataSource(Class<?> driver,String dbUrl,String userName,String userPwd,String sql)
	{

		List<Object> list = new ArrayList<Object>();
		Connection con = null;
		try{
			con = getConnection(driver,dbUrl,userName,userPwd);//获取数据库链接
			if(con==null)
				throw new Exception("获取数据库连接失败!");
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(sql);
			int cols = rs.getMetaData().getColumnCount();
			int i=0;
			Object[] row = null;
			while(rs.next()){
				if(cols==1){
					list.add(rs.getObject(1));
				}
				else{
					row = new Object[cols];
					for(i=0;i<cols;i++)
						row[i] = rs.getObject(i+1);
					list.add(row);
				}
			}
			rs.close();
			st.close();
			con.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		finally{
			try {
				if(con!=null && !con.isClosed())
					con.close();
			} catch (SQLException e) {

				e.printStackTrace();
			}
		}
		return list;
	}


	public static int setDataSource_getCount(Class<?> driver,String dbUrl,String userName,String userPwd,String sql)
	{
		List<Object> list = new ArrayList<Object>();
		Connection con = null;
		int val = 0;
		try{
			con = getConnection(driver,dbUrl,userName,userPwd);//获取数据库链接
			if(con==null)
			{
				throw new Exception("获取数据库连接失败!");
			}
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(sql);

			int cols = rs.getMetaData().getColumnCount();
			int i=0;
			Object[] row = null;
			rs.next();
			val	 = rs.getInt(1);

			rs.close();
			st.close();
			con.close();
		}
		catch(Exception e){			e.printStackTrace();		}
		finally
		{
			try
			{
				if(con!=null && !con.isClosed())
				{
					con.close();
				}
			} catch (SQLException e) {				e.printStackTrace();			}
		}
		return val;
	}




	/**
	 * 例子：con=DbUtil.getConnection(Class.forName("oracle.jdbc.driver.OracleDriver"), "jdbc:oracle:thin:@//localhost:1521/orcl", "system", "admin");
	 * @param driver  	=Class.forName("oracle.jdbc.driver.OracleDriver") \n
	 * @param dbUrl		="jdbc:oracle:thin:@//localhost:1521/orcl"   \n
	 * @param userName	="system"	\n
	 * @param userPwd	="admin" \n
	 * */
	public static Connection getConnection(Class<?> driver,String dbUrl,String userName,String userPwd){
		Connection con = null;
		try{
			Driver d = (Driver) driver.newInstance();
			Properties p = new Properties();
			p.setProperty("user", userName);
			p.setProperty("password", userPwd);

			con = d.connect(dbUrl, p);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return con;
	}



/**
 * 时间:2017年7月31日10:22:06 \n
 * 周路
 *
*C3p0
 * */
	private static String driver;
	private static String dburl;
	private static String user;
	private static String password;
	public static ComboPooledDataSource dataSource;

	private static final DbUtil factory = new DbUtil();

	private Connection conn = null;

	// 初始化数据库连接池
	static {
		Properties prop = new Properties();
		try {
			InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("db.properties");
			prop.load(inputStream);
			driver = prop.getProperty("driver");
			dburl = prop.getProperty("dburl");
			user = prop.getProperty("user");
			password = prop.getProperty("password");
			dataSource = new ComboPooledDataSource();

			dataSource.setUser(user);
			dataSource.setPassword(password);
			dataSource.setJdbcUrl(dburl);
			dataSource.setDriverClass(driver);

			dataSource.setInitialPoolSize(10);
			dataSource.setMinPoolSize(5);
			dataSource.setMaxPoolSize(50);
			dataSource.setMaxStatements(100);
			dataSource.setMaxIdleTime(60);
            System.out.println("\n\n com/ce/util/DbUtil.java-849->初始化C3p0数据库连接池成功 \n\n");
		} catch (IOException e) {
			System.out.println("the file of datasouce configuration is not exist! com/ce/util/DbUtil.java-849->初始化数据库连接池");
			e.printStackTrace();
		} catch (PropertyVetoException e) {
			System.out.println("datasouce config error! com/ce/util/DbUtil.java-852->初始化数据库连接池");
			e.printStackTrace();
		}
		System.out.println("datasouce init finish........! com/ce/util/DbUtil.java-855->初始化数据库连接池");
	}


	public static ComboPooledDataSource getDataSouce(){
		return dataSource;
	}

    //获取连接
    public  Connection getConnection_c3p0() {
        if (null != dataSource) {
            try {
                conn = dataSource.getConnection();
                System.out.println("获取连接 Success! com/ce/util/DbUtil.java-876->getConnection_c3p0()");
            } catch (SQLException e) {
                System.out.println("获取连接 error! com/ce/util/DbUtil.java-878->getConnection_c3p0()");
                e.printStackTrace();
            }
        }
        return conn;
    }
}
